<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>
        Canvas
    </title>
</head>
<style>
    * {
        margin: 0;
        padding: 0;
    }

    canvas {
        border: 1px solid rgb(176, 174, 174);
        box-shadow: 5px 5px 5px #888888;
        border-radius: 10px;
        margin: 20px;
        padding: 20px;
        background-color: #f0f0f0;
    }

    svg {
        border: 1px solid rgb(196, 191, 191);
        box-shadow: 5px 5px 5px #888888;
        border-radius: 10px;
        margin: 20px;
        padding: 20px;
        background-color: #f0f0f0;
    }
</style>

<body>
    <Canvas width="800" height="500"></Canvas>
    <svg width="800" height="500">
        <circle cx="40" cy="40" r="30" fill="red" />
        <circle cx="140" cy="40" r="30" fill="green" />
        <circle cx="240" cy="40" r="30" fill="blue" />
        <circle cx="340" cy="40" r="30" fill="orange" />
        <!-- 文本 -->
        <text x="400" y="50" fill="red" font-size="32" font-family="楷体">送你一朵小红花</text>
        <!-- 折线图 -->
        <polyline points="40 140 80 180 120 140" stroke="black" stroke-width="3" fill="none" />
        <!-- 多边形 -->
        <polygon points="40 240 80 280 120 240" stroke="black" stroke-width="3" fill="yellow" />
        <!-- 矩形 -->
        <rect x="40" y="340" width="80" height="40" stroke="black" stroke-width="3" fill="purple" />
        <!-- 椭圆 -->
        <ellipse cx="80" cy="440" rx="50" ry="20" stroke="black" stroke-width="3" fill="cyan" />
    </svg>
    <canvas id="myCanvas" width="800" height="500"></canvas>
    <canvas id="firstCanvas" width="800" height="500"></canvas>
    <canvas id="secondCanvas" width="300" height="500"></canvas>


</body>

</html>

<script>
    //canvas 标签内容任何操作都需要在JS完成
    // 获取canvas元素
    let canvas = document.querySelector('canvas');
    // 获取canvas的上下文
    let ctx = canvas.getContext('2d');
    //(1)绘制矩形方法1
    ctx.strokeRect(10, 20, 100, 100);
    // (2)绘制矩形方法2
    ctx.fillStyle = 'blue';
    ctx.fillRect(120, 20, 100, 100);
    // (3)绘制圆形arc(x坐标, y坐标, radius半径, startAngle起始角度, endAngle终止角度, anticlockwise是否逆时针)
    ctx.beginPath();
    ctx.arc(50, 200, 50, 0, Math.PI * 2, false);
    // 填充颜色
    ctx.fillStyle = 'cyan';
    ctx.fill();
    // 绘制圆形边框
    ctx.strokeStyle = 'blue';
    ctx.stroke();
    // (4)绘制文本
    ctx.font = '40px 楷体';
    ctx.fillStyle = 'red';
    ctx.fillText('小小的我', 300, 50);
    // (5)绘制线条: 移动到指定位置，绘制线条
    ctx.beginPath();
    ctx.moveTo(200, 250);
    ctx.lineTo(100, 250);
    ctx.lineTo(200, 150);
    // 绘制线段颜色/宽度
    ctx.strokeStyle = 'blue';
    ctx.lineWidth = 5;
    // 闭合路径
    ctx.closePath();
    // 绘制线段的方法
    ctx.stroke();
    // (6)绘制渐变色
    let grd = ctx.createLinearGradient(0, 100, 100, 0);                                                                                         
    grd.addColorStop(0, 'red');
    grd.addColorStop(1, 'pink');
    ctx.fillStyle = grd; // 设置填充样式
    ctx.fillRect(250, 300, 100, 100);
    // (7)绘制阴影
    ctx.shadowBlur = 10; // 模糊度
    ctx.shadowOffsetX = 5; // 阴影偏移量x
    ctx.shadowOffsetY = 5; // 阴影偏移量y
    ctx.shadowColor = 'black';
    ctx.fillRect(400, 300, 100, 100);
    // (8)绘制图片
    let img = new Image(); // 创建图片对象
    img.src = 'https://www.w3school.com.cn/i/eg_tulip.jpg';
    img.onload = function () {
        ctx.drawImage(img, 10, 300, 200, 200); // 绘制图片
    }
    // (9)清除画布
    // ctx.clearRect(0, 0, canvas.width, canvas.height);
    // ctx.clearRect(10, 20, 100, 100); // 清除矩形区域


    // 第二个画布
    let myCanvas = document.getElementById('myCanvas');
    let myCtx = myCanvas.getContext('2d');
    // 动画泡沫
    let arr = [];
    function animate() {
        myCtx.clearRect(0, 0, myCanvas.width, myCanvas.height);
        // 绘制泡沫
        for (let i = 0; i < 5; i++) {
            let x = Math.random() * myCanvas.width;
            let y = Math.random() * myCanvas.height;
            let r = Math.random() * 50 + 5; // 最小半径5
            let color = 'rgba(' + Math.random() * 255 + ',' + Math.random() * 255 + ',' + Math.random() * 255 + ',' + 0.5 + ')';
            arr.push({
                x: x,
                y: y,
                r: r,
                color: color,
                alpha: 1  // 新增透明度属性
            });
        }
        // 绘制泡沫
        for (let i = arr.length - 1; i >= 0; i--) { // 从后向前遍历
            let bubble = arr[i];   // 获取泡沫对象
            myCtx.fillStyle = bubble.color;
            myCtx.beginPath();
            myCtx.arc(bubble.x, bubble.y, bubble.r, 0, Math.PI * 2, false);
            // 根据半径变化逐渐减少透明度
            bubble.alpha = Math.max(0, bubble.alpha - 0.02);
            myCtx.fillStyle = `rgba(${parseInt(bubble.color.slice(5, 8))}, ${parseInt(bubble.color.slice(9, 12))}, ${parseInt(bubble.color.slice(13, 16))}, ${bubble.alpha})`;
            myCtx.fill();
            // 更新位置
            bubble.y += 1;
            // 超出画布范围则移除泡沫
            if (bubble.y > myCanvas.height || bubble.alpha <= 0) {
                arr.splice(i, 1);
            }
        }
        requestAnimationFrame(animate);
    }
    animate(); // 启动动画


    // 第三个画布
    let firstCanvas = document.getElementById('firstCanvas');
    let firstCtx = firstCanvas.getContext('2d');
    // 随机圆动画
    let circles = [];
    const maxCircles = 300; // 设置最大圆的数量
    setInterval(function () {
        if (circles.length >= maxCircles) return; // 如果达到最大数量，不再添加新的圆
        let x = Math.random() * firstCanvas.width;
        let y = Math.random() * firstCanvas.height;
        let r = Math.random() * 50 + 5; // 最小半径5
        let red = Math.random() * 255;
        let green = Math.random() * 255;
        let blue = Math.random() * 255;
        let alpha = 1;
        circles.push({
            x: x,
            y: y,
            r: r,
            red: red,
            green: green,
            blue: blue,
            alpha: alpha
        });
    }, 100);
    setInterval(function () {
        // 随机生成圆
        firstCtx.clearRect(0, 0, firstCanvas.width, firstCanvas.height);
        firstCtx.save();
        for (let i = 0; i < circles.length; i++) {
            if (circles[i].alpha <= 0) {
                circles.splice(i, 1);
                i--; // 调整索引，避免跳过下一个元素
                continue;
            }
            circles[i].r++;
            circles[i].alpha = Math.max(0, circles[i].alpha - 0.01); // 确保 alpha 不小于 0
        }
        for (let i = 0; i < circles.length; i++) {
            firstCtx.beginPath();
            firstCtx.fillStyle = "rgba(" + circles[i].red + "," + circles[i].green + "," + circles[i].blue + "," + circles[i].alpha + ")"; // 半透明红色
            firstCtx.arc(circles[i].x, circles[i].y, circles[i].r, 0, Math.PI * 2, false);
            firstCtx.fill();
        }
        firstCtx.restore();
    }, 1000 / 60);


    
    // 第三个画布
    let secondCanvas = document.getElementById('secondCanvas');
    let secondCtx = secondCanvas.getContext('2d');
    // 随机圆动画
    let secondAttr = [];
    setInterval(function () {
        let r = Math.random() * 20 + 5;
        let x = Math.random() * secondCanvas.width;
        let y = secondCanvas.height - r;
        let red = Math.random() * 255;
        let green = Math.random() * 255;
        let blue = Math.random() * 255;
        let alpha = 1;
        let deg =0;
        let starX =x;
        let starY = y;
        // 曲线运动形式
        let step = Math.random() * 10 + 30;
        secondAttr.push({
            x: x,
            y: y,
            r: r,
            red: red,
            green: green,
            blue: blue,
            alpha: alpha,
            deg: deg,
            starX: starX,
            starY: starY,
            step: step,
        });
    }, 50);
    setInterval(function () {
        // 随机生成圆
        secondCtx.clearRect(0, 0, secondCanvas.width, secondCanvas.height);
        secondCtx.save();
        // 绘制背景动画
        for (let i = 0; i < secondAttr.length; i++) {
            secondAttr[i].deg += 15;
            secondAttr[i].x = secondAttr[i].starX + Math.sin(secondAttr[i].deg*Math.PI/180)*secondAttr[i].step/2;
            secondAttr[i].y = secondAttr[i].starY - (secondAttr[i].deg*Math.PI/180)*secondAttr[i].step;
            if (secondAttr[i].y < 50) {
                secondAttr.splice(i, 1);
                i--; // 调整索引，避免跳过下一个元素
                continue;
            }
        }
        // 绘制圆
        for (let i = 0; i < secondAttr.length; i++) {
            secondCtx.beginPath();
            secondCtx.fillStyle = "rgba(" + secondAttr[i].red + "," + secondAttr[i].green + "," + secondAttr[i].blue + "," + secondAttr[i].alpha + ")"; // 半透明红色
            secondCtx.arc(secondAttr[i].x, secondAttr[i].y, secondAttr[i].r, 0, Math.PI * 2, false);
            secondCtx.fill();
        }
        secondCtx.restore();
    }, 1000 / 50);


    



    

</script>